/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package service.reportCenter.salesReports;

import com.openbrew.openbrewrf.Administration;
import com.openbrew.openbrewrf.FinishedGoodsInventory;
import com.openbrew.openbrewrf.LegacySales;
import com.openbrew.openbrewrf.PackageType;
import com.openbrew.openbrewrf.Sales;
import com.openbrew.openbrewrf.views.POSBeerView;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

/**
 *
 * @author chapmand
 */
@Stateless
@Path("com.openbrew.openbrewrf.salesreport")
public class SalesReportREST {
    @PersistenceContext(unitName = "com.openBrew_openBrewRF_war_1.0PU")
    private EntityManager em;
    
    private Administration admin;
    private List<Sales> saleItems = new ArrayList<Sales>();
    private List<POSBeerView> beers = new ArrayList<POSBeerView>();
    
    private final List<selBeer>selBeers = new ArrayList<selBeer>();
    List<ReportValues> sortedSales = new ArrayList<ReportValues>();
    List<ReportValues> allBeers = new ArrayList<ReportValues>();
    List<ReportValues> specialtyBeers = new ArrayList<ReportValues>();

    // Variables to hold bottles per case.
    public static final int TwentyTwoCase = 12;
    public static final int TwelveCase = 24;
    public static final int SevenFiftyCase = 12;

    // Variables to convert bottles to barrels
    public static final double TTtoBBL = 0.00554435484;
    public static final double TWtoBBL = 0.00302419355;
    public static final double SFtoBBL = 0.00639125933;
    
    public SalesReportREST() {
    }
    
    private void loadSales(){
        saleItems.removeAll(saleItems);
        saleItems = getEntityManager().createNamedQuery("Sales.findAll", Sales.class).getResultList();
    }
    
    private void loadBeers(){
        beers.removeAll(beers);
        beers = getEntityManager().createNamedQuery("POSBeerVew.findAllASC", POSBeerView.class).getResultList();
    }
    
    private void loadAdmin(){
        admin = getEntityManager().createNamedQuery("Administration.findAll", Administration.class).getResultList().get(0);
    }
    
    private int getNumberOfMonths(final int startYear, final int startMonth, final int endYear, final int endMonth){
        double months = 0;
        months = (((double)endYear - (double)startYear)*12)-(double)startMonth + (double)endMonth + 1;
        return (int)months;
    }
    
    private double parseVolume(Sales sale){
        double volume = 0;
        if(sale.getLegacySalesCollection()!=null){
            for(LegacySales ls : sale.getLegacySalesCollection()){
                volume += ((double) ls.getNumHalf() / 2) + ((double) ls.getNumQtr() / 4) 
                        + ((double) ls.getNumSix() / 6);
                volume += ((double) ls.getNumTT() * (double) TwentyTwoCase) * TTtoBBL;
            }
        }
        if(sale.getSalesFGIID()!=null){
            FinishedGoodsInventory fgi = sale.getSalesFGIID();
            PackageType pkg = fgi.getFGIPackageID();
            if(pkg.isServingVessel()){
                volume += ((double)sale.getServingTankVolume());
            } else {
                volume += ((double) sale.getSalesFGIQty() * (double)fgi.getFGIPackageID().getNumItems() * (double)pkg.getPackageTypeVol());
            }
        }
        return volume;
    }
    
    private List<ReportValues> createArraySansCustomers(final int startYear, final int startMonth, final int endYear
                ,final int endMonth, final int beerNum, final boolean spcl, final long custNum){
        List<ReportValues> retVal = new ArrayList<ReportValues>();
        final int totalMonths = getNumberOfMonths(startYear, startMonth, endYear, endMonth);
        int curYear = startYear;
        int curMonth = startMonth;
        for(int i = 0; i<totalMonths; i++){
            double volume = 0;
            for(final Sales sale : saleItems){
                int beerID = 0;
                if(sale.getSalesFGIID()!=null){
                    beerID = sale.getSalesFGIID().getFGIBeerID().getbId();
                } else if(sale.getLegacySalesCollection()!=null){
                    for(LegacySales ls : sale.getLegacySalesCollection()){
                        beerID = ls.getBeerID().getbId();
                    }
                }
                if((sale.getSDate().getYear()==curYear) && (sale.getSDate().getMonth()==curMonth)){
                    if(custNum == 0){
                    } else {
                        if(spcl == false){
                            if((beerNum!=0) && (beerID == beerNum) && (sale.getCustID().getCId()!=custNum)){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            } else if((beerNum == 0) && (sale.getCustID().getCId()!=custNum)) {
                                //array for all beers and all customers;
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        } else {
                            if((beerID!=1)&&(beerID!=2)&&(beerID!=3)
                                    &&(beerID!=4)&&(beerID!=14)&& (sale.getCustID().getCId()!=custNum)){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        }
                    }
                }
            }
            if(spcl){
                retVal.add(new ReportValues(curYear,curMonth,custNum,volume,10000));
            } else {
                retVal.add(new ReportValues(curYear,curMonth,custNum,volume,beerNum));
            }
            if(curMonth == 11){
                curYear++;
                curMonth = 0;
            } else {
                curMonth++;
            }
        }
        return retVal;
    }
    
    private List<ReportValues> createArrayAllCustomers(final int startYear, final int startMonth, final int endYear
                ,final int endMonth, final int beerNum, final boolean spcl, final long custNum){
        List<ReportValues> retVal = new ArrayList<ReportValues>();
        final int totalMonths = getNumberOfMonths(startYear, startMonth, endYear, endMonth);
        int curYear = startYear;
        int curMonth = startMonth;
        for(int i = 0; i<totalMonths; i++){
            double volume = 0;
            for(final Sales sale : saleItems){
                int beerID = 0;
                if(sale.getSalesFGIID()!=null){
                    beerID = sale.getSalesFGIID().getFGIBeerID().getbId();
                } else if(sale.getLegacySalesCollection()!=null){
                    for(LegacySales ls : sale.getLegacySalesCollection()){
                        beerID = ls.getBeerID().getbId();
                    }
                }
                if((sale.getSDate().getYear()==curYear) && (sale.getSDate().getMonth()==curMonth)){
                    if(custNum == 0){
                        if(spcl == false){
                            if((beerNum!=0) && (beerID == beerNum)){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            } else if(beerNum == 0) {
                                //array for all beers and all customers;
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        } else {
                            boolean go = true;
                            for(final selBeer sb : selBeers){
                                if(sb.getBeer().getbId() == beerID){
                                    go = false;
                                }
                            }
                            if(go){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        }
                    } else {
                        if(spcl == false){
                            if((beerNum!=0) && (beerID == beerNum) && (sale.getCustID().getCId()==custNum)){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            } else if((beerNum == 0) && (sale.getCustID().getCId()==custNum)) {
                                //array for all beers and all customers;
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        } else {
                            boolean go = true;
                            for(final selBeer sb : selBeers){
                                if(sb.getBeer().getbId() == beerID){
                                    go = false;
                                }
                            }
                            if((go) && (sale.getCustID().getCId()==custNum)){
                                final double tempVolume = parseVolume(sale);
                                volume = volume + tempVolume;
                            }
                        }
                    }
                }
            }
            if(spcl){
                retVal.add(new ReportValues(curYear,curMonth,custNum,volume,10000));
            } else {
                retVal.add(new ReportValues(curYear,curMonth,custNum,volume,beerNum));
            }
            if(curMonth == 11){
                curYear++;
                curMonth = 0;
            } else {
                curMonth++;
            }
        }
        return retVal;
    }
    
    private void loadArrays(final int startYear, final int startMonth, final int endYear, final int endMonth
            , final SalesReportType type, long id){
        selBeers.removeAll(selBeers);
        for(final POSBeerView beer : beers){
            selBeers.add(new selBeer(beer, true));
        }
        for(final selBeer sb : selBeers){
            List<ReportValues> rv = sb.getReportValues();
            rv.removeAll(rv);
            if(type == SalesReportType.ALL_SALES_DATA){
                rv = createArrayAllCustomers(startYear, startMonth, endYear, endMonth
                        , sb.getBeer().getbId(),false,0);
            } else if(type == SalesReportType.TAPROOM_SALES_DATA){
                rv = createArrayAllCustomers(startYear, startMonth, endYear, endMonth
                        ,sb.getBeer().getbId(),false,admin.getTrCust().getCId());
            } else if(type == SalesReportType.OUTSIDE_SALES_DATA){
                rv = createArraySansCustomers(startYear, startMonth, endYear, endMonth
                        ,sb.getBeer().getbId(),false,admin.getTrCust().getCId());
            } else if(type == SalesReportType.CUSTOMER_SALES_DATA){
                rv = createArrayAllCustomers(startYear, startMonth, endYear, endMonth
                        ,sb.getBeer().getbId(),false,id);
            }
            sb.setReportValues(rv);
        }

        //now we know how many months we need and we know the start and end years, lets build
        //arrays of Report Values and parse them accordingly.
        allBeers.removeAll(allBeers);
        specialtyBeers.removeAll(specialtyBeers);

        if(type == SalesReportType.ALL_SALES_DATA){
            allBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,false,0);
            specialtyBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,true,0);
        } else if(type == SalesReportType.TAPROOM_SALES_DATA){
            allBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,false,admin.getTrCust().getCId());
            specialtyBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,true,admin.getTrCust().getCId());
        } else if(type == SalesReportType.OUTSIDE_SALES_DATA){
            allBeers = createArraySansCustomers(startYear, startMonth, endYear, endMonth,0,false,admin.getTrCust().getCId());
            specialtyBeers = createArraySansCustomers(startYear, startMonth, endYear, endMonth,0,true,admin.getTrCust().getCId());
        } else if(type == SalesReportType.CUSTOMER_SALES_DATA){
            allBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,false,id);
            specialtyBeers = createArrayAllCustomers(startYear, startMonth, endYear, endMonth,0,true,id);
        } 
    }
    
    @GET
    @Path("{startYear}/{startMonth}/{endYear}/{endMonth}/{type}/{id}")
    @Produces(MediaType.APPLICATION_XML)
    public SReport find(@PathParam("startYear") int startYear
            , @PathParam("startMonth") int startMonth
            , @PathParam("endYear") int endYear
            , @PathParam("endMonth") int endMonth
            , @PathParam("type") int type
            , @PathParam("id") long id) {
        //Find report type.
        SalesReportType srt = SalesReportType.getType(type);
        
        //load all items needed to run report.
        loadAdmin();
        loadSales();
        loadBeers();
        
        //load arrays.
        loadArrays(startYear, startMonth, endYear, endMonth, srt, id);
        
        SReport sr = new SReport();
        sr.setAllBeers(allBeers);
        sr.setSpecialtyBeers(specialtyBeers);
        sr.setIndividualBeers(selBeers);
        sr.setResult("Success!");
        return sr;
    }
    
    protected EntityManager getEntityManager() {
        return em;
    }
}
